/*
 * Copyright (C) 2019 ByteDance Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bytedance.scene.utlity;

import com.bytedance.scene.Scene;
import com.bytedance.scene.SceneParent;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.fraction.FractionManager;
import ohos.aafwk.ability.fraction.FractionScheduler;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentParent;
import ohos.agp.utils.TextTool;
import ohos.app.Context;

import java.util.List;

/**
 * Created by JiangQi on 7/30/18.
 */
public class Utility {
    private static final int NUM255 = 255;
    private static final int NUM24 = 24;
    private static final int NUMFF = 0x00ffffff;

    public static void removeFromParentView(Component view) {
        ComponentParent viewParent = view.getComponentParent();
        if (viewParent instanceof ComponentParent) {
            viewParent.removeComponent(view);
        }
    }

    public static boolean isActivityStatusValid(Ability activity) {
        if (activity == null) {
            return false;
        }
        if (activity.isTerminating()) {
            return false;
        }
        return true;
    }

    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }

    public static String requireNonEmpty(String obj, String message) {
        if (TextTool.isNullOrEmpty(obj)) {
            throw new IllegalArgumentException(message);
        }
        return obj;
    }

    public static void commitFragment(FractionManager fragmentManager, FractionScheduler transaction, boolean commitNow) {
        transaction.submit();
    }

    public static void buildShortClassTag(Object cls, StringBuilder out) {
        if (cls == null) {
            out.append("null");
        } else {
            String simpleName = cls.getClass().getSimpleName();
            if (simpleName == null || simpleName.length() <= 0) {
                simpleName = cls.getClass().getName();
                int end = simpleName.lastIndexOf('.');
                if (end > 0) {
                    simpleName = simpleName.substring(end + 1);
                }
            }
            out.append(simpleName);
            out.append('{');
            out.append(Integer.toHexString(System.identityHashCode(cls)));
            out.append('}');
        }
    }

    public static String getViewHierarchy(Scene scene) {
        StringBuilder desc = new StringBuilder();
        getViewHierarchy(scene, desc, 0);
        return desc.toString();
    }

    private static void getViewHierarchy(Scene scene, StringBuilder desc, int margin) {
        desc.append(getViewMessage(scene, margin));
        if (scene instanceof SceneParent) {
            margin++;
            SceneParent sceneParent = (SceneParent) scene;
            List<Scene> list = sceneParent.getSceneList();
            for (int i = 0; i < list.size(); i++) {
                getViewHierarchy(list.get(i), desc, margin);
            }
        }
    }

    public static String getIdName(Context context, int viewId) {
        return String.valueOf(viewId);
    }

    private static String getViewMessage(Scene scene, int marginOffset) {
        Scene parentScene = scene.getParentScene();
        String repeated = new String(new char[marginOffset]).replace("\0", "    ");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(repeated + "[" + scene.getClass().getSimpleName() + "] ");

        if (parentScene != null) {
            stringBuilder.append(((SceneParent) parentScene).getSceneDebugInfo(scene));
        }

        String resourceId = null;
        if (scene.getApplicationContext() != null && scene.getView() != null && scene.getView().getId() != Component.ID_DEFAULT) {
            resourceId = getIdName(scene.requireApplicationContext(), scene.getView().getId());
        }
        if (resourceId != null) {
            stringBuilder.append("viewId: " + resourceId + " ");
        }
        stringBuilder.append("\n");
        return stringBuilder.toString();
    }

    public static int getColorWithAlpha(float alpha, int baseColor) {
        int a = Math.min(NUM255, Math.max(0, (int) (alpha * NUM255))) << NUM24;
        int rgb = NUMFF & baseColor;
        return a + rgb;
    }
}
